#pragma once

#include "my_conn.h"
#include "comm/my_defs.h"
#include "comm/my_inet.h"

////////////////// tcp listener //////////////////

typedef struct my_tcp_listener_s my_tcp_listener_t;

struct my_tcp_listener_s {
    const char          *listen_addr;
    int                 backlog;
    unsigned            nodelay:1;
    unsigned            quickack:1;
    unsigned            reuseport:1;
    unsigned            reuseaddr:1;
    unsigned            ipv6only:1;

    int                 sockfd;
    my_address_t        address;
    my_event_handler_t  accept_handler;

    my_tcp_listener_t   *next;
};

static inline void
my_tcp_listener_init(my_tcp_listener_t *listener)
{
    listener->sockfd = INVALID_FD;
}

extern my_tcp_listener_t g_tcp_listener_list;

static inline void
my_tcp_listener_register(my_tcp_listener_t *listener)
{
    listener->next = g_tcp_listener_list.next;
    g_tcp_listener_list.next = listener;
}

////////////////// tcp accepter //////////////////

void my_tcp_accepter_start();

void my_tcp_accepter_stop();


////////////////// tcp connect //////////////////

typedef struct {
    unsigned            nodelay:1;
    unsigned            quickack:1;
} my_tcp_connect_opts_t;

typedef void (*my_tcp_connect_handle_pt)(void *data,
    my_conn_t *conn, my_result_t res);

void my_tcp_connect_setup(my_address_t *address,
    int64_t timeout_ms, my_tcp_connect_opts_t *opts,
    my_tcp_connect_handle_pt connect_handler, void *data);